package com.smart.mac.common;

import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.net.ConnectException;
import java.nio.file.AccessDeniedException;
import java.util.List;
import java.util.concurrent.CompletionException;

@Slf4j
@RestControllerAdvice
public class GlobalBizExceptionHandler {

    public GlobalBizExceptionHandler() {
    }

    @ExceptionHandler({IllegalArgumentException.class})
    @ResponseStatus(HttpStatus.OK)
    public R handleIllegalArgumentException(IllegalArgumentException exception) {
        log.info("非法参数,ex = {}", exception.getMessage(), exception);
        return R.failed(exception.getMessage());
    }

    @ExceptionHandler({AccessDeniedException.class})
    @ResponseStatus(HttpStatus.FORBIDDEN)
    public R handleAccessDeniedException(AccessDeniedException e) {
        log.warn("拒绝授权异常信息 ex={}", e.getMessage());
        return R.failed(e.getLocalizedMessage());
    }

    @ExceptionHandler({MethodArgumentNotValidException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public R handleBodyValidException(MethodArgumentNotValidException exception) {
        List<FieldError> fieldErrors = exception.getBindingResult().getFieldErrors();
        log.warn("参数绑定异常,ex = {}", ((FieldError)fieldErrors.get(0)).getDefaultMessage());
        return R.failed(((FieldError)fieldErrors.get(0)).getDefaultMessage());
    }

    @ExceptionHandler({BindException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public R bindExceptionHandler(BindException exception) {
        List<FieldError> fieldErrors = exception.getBindingResult().getFieldErrors();
        log.info("参数绑定异常,ex = {}", ((FieldError)fieldErrors.get(0)).getDefaultMessage());
        return R.failed(((FieldError)fieldErrors.get(0)).getDefaultMessage());
    }

    @ExceptionHandler({DuplicateKeyException.class})
    @ResponseStatus(HttpStatus.OK)
    public R handleDuplicateKeyException(DuplicateKeyException e) {
        log.warn("数据库唯一索引重复", e);
        return R.failed((Object)null, "已存在该记录");
    }


    @ExceptionHandler({ConnectException.class})
    public R connectException(ConnectException exception) {
        log.error("连接超时", exception);
        return R.failed((Object)null, "连接超时，请稍后重试");
    }

    @ExceptionHandler({CompletionException.class})
    public R completionException(CompletionException exception) {
        log.info("异步任务异常", exception);
        return R.failed((Object)null, exception.getCause().getMessage());
    }

    @ExceptionHandler({Exception.class})
    public R businessException(Exception exception) {
        log.info("业务异常", exception);
        return R.failed((Object)null, exception.getMessage());
    }
}
